package cn.xuchunh.campusbbs.widget;

import android.graphics.drawable.Animatable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.support.annotation.Nullable;

import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.controller.BaseControllerListener;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.DraweeHolder;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.image.ImageInfo;
import com.facebook.imagepipeline.memory.PooledByteBuffer;
import com.facebook.imagepipeline.memory.PooledByteBufferInputStream;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;

import java.io.BufferedInputStream;
import java.io.IOException;

import pl.droidsonroids.gif.GifDrawable;

/**
 * Created by XuChunH on 2015/9/17.
 */
public class GifRequester implements Drawable.Callback {
    private int id;
    private int start;
    private int end;
    private AdvancedTextView textView;
    DraweeHolder<GenericDraweeHierarchy> mDraweeHolder;
    private CloseableReference<PooledByteBuffer> bytes;
    private GifDrawable mGifDrawable;

    public GifRequester(AdvancedTextView textView) {
        this.textView = textView;
        GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(textView.getResources()).build();
        mDraweeHolder = DraweeHolder.create(hierarchy, textView.getContext());
    }

    public void setImageUri(Uri uri) {
        ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(uri).build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        final DataSource<CloseableReference<PooledByteBuffer>> dataSource = imagePipeline.fetchEncodedImage(imageRequest, this);
        DraweeController controller = Fresco.newDraweeControllerBuilder()
                .setOldController(mDraweeHolder.getController())
                .setImageRequest(imageRequest)
                .setControllerListener(new BaseControllerListener<ImageInfo>() {
                    @Override
                    public void onFinalImageSet(String s, @Nullable ImageInfo imageInfo, @Nullable Animatable animatable) {
                        try {
                            if (bytes == null) {
                                bytes = dataSource.getResult();
                            }
                            if (bytes != null) {
                                PooledByteBuffer pooledByteBuffer = bytes.get();
                                PooledByteBufferInputStream sourceIs = new PooledByteBufferInputStream(pooledByteBuffer);
                                BufferedInputStream bis = new BufferedInputStream(sourceIs);
                                mGifDrawable = new GifDrawable(bis);
                                mGifDrawable.setBounds(0, 0, mGifDrawable.getIntrinsicWidth(), mGifDrawable.getIntrinsicHeight());
                                mGifDrawable.setCallback(GifRequester.this);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            dataSource.close();
                            CloseableReference.closeSafely(bytes);
                            textView.notifyGifRequestFinished(id);
                        }
                    }
                })
                .setTapToRetryEnabled(true)
                .build();
        mDraweeHolder.setController(controller);
    }

    public GifDrawable getGifDrawable() {
        return mGifDrawable;
    }

    public DraweeHolder<GenericDraweeHierarchy> getDraweeHolder() {
        return mDraweeHolder;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getStart() {
        return start;
    }

    public void setStart(int start) {
        this.start = start;
    }

    public int getEnd() {
        return end;
    }

    public void setEnd(int end) {
        this.end = end;
    }

    @Override
    public void invalidateDrawable(Drawable who) {
        textView.invalidate();
    }

    @Override
    public void scheduleDrawable(Drawable who, Runnable what, long when) {
        textView.postDelayed(what, when);
    }

    @Override
    public void unscheduleDrawable(Drawable who, Runnable what) {
        textView.removeCallbacks(what);
    }
}
